﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using Google.GData.Client;
using DataType;

namespace UILibrary
{
    public class TreeViewSites
    {
        internal delegate void AddTreeViewNodeDelegate(TreeNode Node);
        internal delegate TreeNode AddTreeNodeCollectionDelegateA(TreeNodeCollection Parent, AtomEntry Entry);
        internal delegate void AddTreeNodeCollectionDelegateB(TreeNodeCollection Parent, AtomEntry Entry);
        internal delegate void VoidDelegate();
        internal delegate TreeNode GetSelectedNodeDelegate(TreeNode root);


        private ImageList m_AppImageList = new ImageList();
        private List<AtomEntry> all = new List<AtomEntry>();
        private TreeNode m_NoFolder;
        public TreeView m_TreeView;
        public string m_sitename { get; set;} 

        public TreeViewSites(TreeView documentsView, string sitename)
        {
            m_sitename = sitename;

            m_TreeView = documentsView;
            m_AppImageList.ColorDepth = ColorDepth.Depth32Bit;
            m_AppImageList.TransparentColor = Color.Transparent;
            m_AppImageList.ImageSize = new Size(20, 20);
            m_AppImageList.Images.Add("Site", Properties.Resources.Sites);
            m_TreeView.ImageList = m_AppImageList;
        }

        public void InitTree()
        {
            all.Clear();
            m_NoFolder = null;
            m_NoFolder = new TreeNode(m_sitename);
            m_NoFolder.SelectedImageKey = "Site";
            m_NoFolder.ImageKey = "Site";


            if (m_TreeView.InvokeRequired)
            {
                VoidDelegate dlgt = new VoidDelegate(this.ClearTree);
                m_TreeView.Invoke(dlgt);
            }
            else
                m_TreeView.Nodes.Clear();

            if (m_TreeView.InvokeRequired)
            {
                AddTreeViewNodeDelegate AddNode = new AddTreeViewNodeDelegate(this.AddTreeViewNode);
                m_TreeView.Invoke(AddNode, new object[] { m_NoFolder });
            }
            else
                m_TreeView.Nodes.Add(m_NoFolder);
        }

        private void ClearTree()
        {
            m_TreeView.Nodes.Clear();
        }

        public void CleanUp()
        {
            m_TreeView.Nodes.Clear();
            m_TreeView.Nodes.Add("No items...");
        }

        private void AddTreeViewNode(TreeNode Node)
        {
            m_TreeView.Nodes.Add(Node);
        }

        public void AddDocumentToCollection(AtomEntry entry)
        {
            all.Add(entry);
        }

        public void ShowTree()
        {
            foreach (AtomEntry entry in all) AddDocument2UI(entry);
        }

        private const string SITES_NAMESPACE = "http://schemas.google.com/sites/2008";
        private const string PARENT_REL = SITES_NAMESPACE + "#parent";

        private AtomLink getCategoryParent(AtomLinkCollection links)
        {
            foreach (AtomLink link in links)
            {
                if (link.Rel == PARENT_REL)
                {
                    return link;
                }
            }
            return null;
        }

        private AtomEntry GetDocumentParent(AtomEntry entry)
        {
            AtomLink link = getCategoryParent(entry.Links);
            if (link == null) return null;
            foreach (AtomEntry e in all)
            {
                if (e.Id.Uri.Content == link.HRef.Content) return e;
            }
            return null;
        }

        public void AddDocument2UI(AtomEntry document)
        {
            //all.Add(document);
            // let's add those with no parents for the toplevel
            TreeNode n = null;
            n = FindEntry(m_NoFolder.Nodes, document);
            if (n != null) return;

            AtomEntry parent = GetDocumentParent(document);
            
            if (parent == null)
            {
                n = m_NoFolder;
            }
            else
            {
               n = FindEntry(m_NoFolder.Nodes, parent);
               /*
                * if (n == null)
               {
                   //Add Parent
                   if (m_TreeView.InvokeRequired)
                   {
                       AddTreeNodeCollectionDelegateA AddTreeNode = new AddTreeNodeCollectionDelegateA(this.AddToTreeView);
                       n = (TreeNode)m_TreeView.Invoke(AddTreeNode, new object[] { m_NoFolder.Nodes, parent });
                   }
                   else
                       n = AddToTreeView(m_NoFolder.Nodes, parent);
               } **/
               if (n == null)
               {
                   AddDocument2UI(parent);
                   n = FindEntry(m_NoFolder.Nodes, parent);
               }
            }

            TreeNode nn;
            if (m_TreeView.InvokeRequired)
            {
                AddTreeNodeCollectionDelegateA AddTreeNode = new AddTreeNodeCollectionDelegateA(this.AddToTreeView);
                nn = (TreeNode)m_TreeView.Invoke(AddTreeNode, new object[] { n.Nodes, document });
            }
            else
                nn = AddToTreeView(m_NoFolder.Nodes, document);

        }

       
        private TreeNode FindEntry(TreeNodeCollection coll, AtomEntry entry)
        {
            foreach (TreeNode n in coll)
            {
                // title is not specific enough
                AtomEntry d = n.Tag as AtomEntry;
                if (d.Id == entry.Id)
                    return n;
                TreeNode x = FindEntry(n.Nodes, entry);
                if (x != null)
                    return x;
            }
            return null;
        }

        private TreeNode AddToTreeView(TreeNodeCollection parent, AtomEntry doc)
        {
            TreeNode node = new TreeNode(doc.Title.Text);
            node.Tag = doc;

            node.ImageKey = "Site";
            node.SelectedImageKey = "Site";
           

            parent.Add(node);
            return node;

        }
        //internal delegate TreeNode GetSelectedNodeDelegate(TreeNode root);

        private TreeNode GetSelectedNodeThreadSafe(TreeNode root)
        {
            if (m_TreeView.SelectedNode == root) return null;
            return m_TreeView.SelectedNode;
        }

        public TreeNode GetSelectedNode()
        {
            TreeNode nn;
            if (m_TreeView.InvokeRequired)
            {
                GetSelectedNodeDelegate AddTreeNode = new GetSelectedNodeDelegate(this.GetSelectedNodeThreadSafe);
                nn = (TreeNode)m_TreeView.Invoke(AddTreeNode, new object[] { m_NoFolder });
            }
            else
                nn = GetSelectedNodeThreadSafe(m_NoFolder);

            return nn;
        }
    }
}
